package com.beidu.lottery.call.utils;

import cn.hutool.core.date.LocalDateTimeUtil;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class LocalDateUtils {

    private static final String format = "yyyy-MM-dd HH:mm:ss";
    private static final String hourFormat = "yyyy-MM-dd HH:mm";
    private static final String dayFormat = "yyyyMMdd";
    private static final String monthFormat = "yyyy-MM";
    private static final String parseFormat = "yyyy/MM/dd HH:mm:ss";
    private static final String parseFormat2 = "yyyy-MM-dd HH:mm:ss";
    private static final String parseFormat3 = "yyyyMMddHHmmss";
    private static final String parseFormat3WithoutYear = "MMddHHmmss";

    /**
     * 计算指定时间到本周的最后一天还有多少秒
     *
     * @param startTime 计算时间
     * @return 秒
     */
    public static long calWeekSeconds(LocalDateTime startTime) {
        if (startTime == null) {
            // 获取当前日期时间
            startTime = LocalDateTime.now();
        }
        // 计算本周的周日
        LocalDateTime sunday = startTime.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
        LocalDateTime targetTime = sunday.withHour(23).withMinute(59).withSecond(59);
        return ChronoUnit.SECONDS.between(startTime, targetTime);
    }

    /**
     * 计算指定时间到今天还有多少秒
     *
     * @param startTime 计算时间
     * @return 秒
     */
    public static long calTodaySeconds(LocalDateTime startTime) {
        if (startTime == null) {
            // 获取当前日期时间
            startTime = LocalDateTime.now();
        }
        // 构造当天23点59分的LocalDateTime（使用相同的日期部分）
        LocalDateTime endOfDay = LocalDateTime.now().withHour(23).withMinute(59).withSecond(0).withNano(0);
        // 计算时间差（秒）
        return ChronoUnit.SECONDS.between(startTime, endOfDay);
    }

    /**
     * 获取传入日期在本周的最后一天
     *
     * @param startDate 计算日期
     * @return 本周的最后一天
     */
    public static LocalDate lastDayOfWeek(LocalDate startDate) {
        // 使用TemporalAdjusters获取本周的最后一天（周日）
        // 注意：TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)将返回周日，但如果当天就是周日，它也会返回当前日期
        return startDate.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
    }

    public static long duringDays(LocalDateTime start, LocalDateTime end) {
        long daysNum = end.toLocalDate().toEpochDay() - start.toLocalDate().toEpochDay();
        return daysNum;
    }

    public static long duringDays(LocalDate start, LocalDate end) {
        long daysNum = end.toEpochDay() - start.toEpochDay();
        return daysNum;
    }

    //本年年末
    public static String startDate() {
        LocalDateTime firstday = LocalDateTime.now().minusYears(1).with(TemporalAdjusters.firstDayOfYear()).withHour(0).withMinute(0).withSecond(0);
        String startDate = LocalDateTimeUtil.format(firstday, format);
        return startDate;
    }

    //去年年初
    public static String endDate() {
        LocalDateTime lastDay = LocalDateTime.now().with(TemporalAdjusters.lastDayOfYear()).withHour(23).withMinute(59).withSecond(59);
        String endDate = LocalDateTimeUtil.format(lastDay, format);
        return endDate;
    }

    //月第一天
    public static String firstDateTime(String month) {
        return month + "-01 00:00:00";
    }

    //月最后一天
    public static String lastDateTime(String month) {
        LocalDateTime time = LocalDateTimeUtil.parse(month + "-01 23:59:59", format);
        LocalDateTime lastDate = time.with(TemporalAdjusters.lastDayOfMonth());
        return LocalDateTimeUtil.format(lastDate, format);
    }

    /**
     * 获取两个日期之间的月份的方法
     *
     * @param minDate
     * @param maxDate
     * @return
     */
    public static List<String> getMonthBetween(String minDate, String maxDate) {

        List<String> result = new ArrayList();

        try {

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");//格式化为年月

            Calendar min = Calendar.getInstance();

            Calendar max = Calendar.getInstance();

            min.setTime(sdf.parse(minDate));

            min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);

            max.setTime(sdf.parse(maxDate));

            max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

            Calendar curr = min;

            while (curr.before(max)) {

                result.add(sdf.format(curr.getTime()));

                curr.add(Calendar.MONTH, 1);

            }

        } catch (ParseException e) {

            e.printStackTrace();

        }

        return result;

    }

    /**
     * 获取两个日期之间的所有日期的方法
     *
     * @param startTime
     * @param endTime
     * @return
     */
    public static List<String> getDayBetween(String startTime, String endTime) {

        // 返回的日期集合
        List<String> days = new ArrayList<String>();

        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date start = dateFormat.parse(startTime);
            Date end = dateFormat.parse(endTime);

            Calendar tempStart = Calendar.getInstance();
            tempStart.setTime(start);

            Calendar tempEnd = Calendar.getInstance();
            tempEnd.setTime(end);
            tempEnd.add(Calendar.DATE, +1);// 日期加1(包含结束)
            while (tempStart.before(tempEnd)) {
                days.add(dateFormat.format(tempStart.getTime()));
                tempStart.add(Calendar.DAY_OF_YEAR, 1);
            }

        } catch (ParseException e) {
            e.printStackTrace();
        }

        return days;

    }

    public static String hourFormat(LocalDateTime time) {
        return time.format(DateTimeFormatter.ofPattern(hourFormat));
    }

    public static String format(LocalDateTime time) {
        return time.format(DateTimeFormatter.ofPattern(format));
    }

    //获取当前周几
    public static int getDayOfWeek() {
        return LocalDate.now().getDayOfWeek().getValue();
    }

    //获取当前年月日时分
    public static String getDateTime() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(hourFormat));
    }

    //获取当前年月日时分
    public static LocalDateTime parseTime(String str) {
        return LocalDateTime.parse(str + " 00:00:00", DateTimeFormatter.ofPattern(parseFormat));
    }

    //获取当前年月日时分
    public static LocalDateTime parseTime2(String str) {
        return LocalDateTime.parse(str + " 00:00:00", DateTimeFormatter.ofPattern(parseFormat2));
    }

    //获取当前年月日时分秒
    public static String getDateTimes() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(format));
    }

    //获取当前年月
    public static String getDateMonth() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(monthFormat));
    }

    //获取当前年月日
    public static String getDay() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dayFormat));
    }

    /**
     * 获取时间字符串（格式：yyyyMMddHHmmss）
     *
     * @author 北渡
     */
    public static String getTimestamp() {
        SimpleDateFormat sdf = new SimpleDateFormat(parseFormat3);
        return sdf.format(new Date());
    }

    /**
     * 获取不包含年份的时间字符串（格式：MMddHHmmss）
     *
     * @author 北渡
     */
    public static String getTimestampWithoutYear() {
        SimpleDateFormat sdf = new SimpleDateFormat(parseFormat3WithoutYear);
        return sdf.format(new Date());
    }

    /**
     * 获取从当前时间开始到指定时间的时间戳(秒)
     *
     * @author 北渡
     */
    public static long getTimestampTo(LocalDateTime targetTime) {
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 计算当前时间到目标时间的Duration
        Duration duration = Duration.between(now, targetTime);
        // 转换为秒
        return duration.getSeconds();
    }

    /**
     * 获取从当前时间开始到今天23:59:59的时间戳(秒)
     *
     * @author 北渡
     */
    public static long getTodayExpireTimestamp() {
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 设置为今天23:59:59
        LocalDateTime todayEnd = now.withHour(23).withMinute(59).withSecond(59);
        // 计算时间差并转换为秒
        return Duration.between(now, todayEnd).getSeconds();
    }

}
